package sk.talker.atlantis.icefaces.beans;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.SocketException;

import org.apache.commons.net.telnet.EchoOptionHandler;
import org.apache.commons.net.telnet.InvalidTelnetOptionException;
import org.apache.commons.net.telnet.SimpleOptionHandler;
import org.apache.commons.net.telnet.SuppressGAOptionHandler;
import org.apache.commons.net.telnet.TelnetClient;
import org.apache.commons.net.telnet.TerminalTypeOptionHandler;

public class TalkerTelnetClient {
	private TelnetClient telnetClient;
	
	private BufferedReader talkerIn;
	private PrintWriter talkerOut;
	
	public BufferedReader getTalkerInput() {
		return talkerIn;
	}
	
	public PrintWriter getTalkerOutput() {
		return talkerOut;
	}
	
	public String connect(String username, String password) {
		//TODO connect socket..
		//TODO make inputstream, outputstream..
		
		readUntil("Tvoja prezyvka: ");
		write(username);
		readUntil("Tvoje heslo: ");
		write(password);
		
		if (loggedIn()) return "success";
		else return "failure";
	}
	
	private boolean loggedIn(){
		try {
			//should be 13 (CR)
			talkerIn.read();
			//should be 10 (LF)
			talkerIn.read();
			
			int logChar = talkerIn.read();
			//the escape code coming - successfully logged in
			if (logChar == 27) {
				return true;
			}
			//
			else if (logChar == 13) {
				//TODO zavri stream a socket
				return false;
			}
			return false;
		} catch (IOException e) {
			e.printStackTrace();
			//TODO zavri stream a socket?
			return false;
		}
	}
	
	private void processAnsiEscapeCode() {
		//TODO
	}
	
	private String parseAnsiColorCode() {
		//TODO		
		return null;
	}
	
	
	

	public String readUntil(String pattern) {
		try {
			char lastChar = pattern.charAt(pattern.length() - 1);
			StringBuffer sb = new StringBuffer();
			char ch = (char)telnetIn.read();
			while(true) {
				System.out.print(ch);
				sb.append(ch);
				if(ch == lastChar) {
					if(sb.toString().endsWith(pattern)) {
						return sb.toString();
					}
				}
				ch = (char)telnetIn.read();
			}
		}
		catch(Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public void write(String value) {
		try {
			telnetOut.println(value);
			telnetOut.flush();
			//System.out.println("--napisala si: \"" + value + "\"");
		}
		catch(Exception e) {
			e.printStackTrace();
		}
	}

	public void disconnect() {
		try {
			telnetClient.disconnect();
		}
		catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public void read(BufferedReader telnetIn) {
		int characterInt = 0;
		boolean ready = true;
		try {
			while(true) {				
				if (!telnetIn.ready()) {
					//write(" ", telnetOut);
					if (ready) {
						System.out.print("!=ready\n");
						ready = false;
					}
					//write(clientIn.readLine());
					//Thread.sleep(100);
				}
				else {
					ready = true;
					characterInt = telnetIn.read();
					if (characterInt == -1) {
						break;
					}
					else {
						System.out.print((char)characterInt);
					}					
				}
			}
			System.out.println("--EOS--");
		} catch (IOException e) {
			System.out.println("--IOException--");
			e.printStackTrace();
		}
		finally {
			System.out.println("--finally--");
		}
		
	}

	public static void main(String[] args) {
		telnetClient = new TelnetClient();
		
		EchoOptionHandler echoopt = new EchoOptionHandler(true, false, true, false);
		TerminalTypeOptionHandler ttopt = new TerminalTypeOptionHandler("VT100", false, false, true, false);
        SuppressGAOptionHandler gaopt = new SuppressGAOptionHandler(true, true, true, true);
		SimpleOptionHandler envopt = new SimpleOptionHandler(39, false, false, true, true) {
			public int[] answerSubnegotiation(int[] suboptionData, int suboptionLength) {
				return new int[]{39, 0};
			}
		};
		SimpleOptionHandler nawsopt = new SimpleOptionHandler(31, false, false, true, true) {
			public int[] answerSubnegotiation(int[] suboptionData, int suboptionLength) {
				return new int[]{31, 0};
			}
		};
		try {
			telnetClient.addOptionHandler(echoopt);
			telnetClient.addOptionHandler(ttopt);
			telnetClient.addOptionHandler(gaopt);
			telnetClient.addOptionHandler(envopt);
			telnetClient.addOptionHandler(nawsopt);
		} catch (InvalidTelnetOptionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		try {
			telnetClient.connect("talker.sk", 8000);
		} catch (SocketException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		Thread reader = new Thread(new TalkerTelnetBean());
		telnetClient.registerNotifHandler(new TalkerTelnetBean());
		reader.start();

		PrintWriter telnetOut = new PrintWriter(telnetClient.getOutputStream(), true);
		BufferedReader clientIn = new BufferedReader(new InputStreamReader(System.in));
		
		while(true) {
			try {
				telnetOut.println(clientIn.readLine());
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	public void run() {
		try {
			BufferedReader telnetIn = new BufferedReader(new InputStreamReader(telnetClient.getInputStream(), "ISO-8859-1"));
			read(telnetIn);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	
	
}
